home *** CD-ROM | disk | FTP | other *** search
- #pragma once
-
- #include <setjmp.h>
-
- /* exception state codes */
- enum { EXCEPTION_SET, EXCEPTION_RETRY, EXCEPTION_FAIL };
-
- /* Global exception information, contains the environment to jump to when
- an exception is raised and information on the error which raised the
- exception. */
- typedef struct {
- void *jmpenv; /* current environment to long jump to */
- OSErr err; /* error code of error that triggered exception */
- short action; /* index to string describing action being attempted
- when exception occurred */
- CStr255 object; /* object uppon which the action was being attempted */
- CStr255 explanation; /* an explanation of the exception */
- } ExceptionType;
-
- /* Structure used for saving the state in a TRY handler. */
- typedef struct {
- Boolean failed; /* True if the call to setjmp returns kExceptionFail,
- meaning an exception was raised. If true, then the TRY
- part of the handler is skipped. */
- OSErr err; /* Saved gException.err, needed by RETRY and NOPROPAGATE
- so they can reset the error. Merely resetting to noErr
- wouldn't work in nested failure/retry situations (e.g.,
- a retry that occurs during recovery from another
- failure). */
- jmp_buf env; /* The environment to jump to. While executing the TRY
- handler the global gExecetion.jmpenv is set to this. */
- void *svenv; /* The prior value of gExecetion.jmpenv. Used to restore
- to prior jump environment when no longer executing the
- TRY part of the handler. This allows TRY handlers to be
- nested. The global gExecetion.jmpenv is reset to svenv
- as soon as the TRY part of the handler has been executed
- (or skipped), and before the CATCH or CLEANUP handlers
- are executed, so that a failure within those handlers
- will not go into an infinite loop but rather will jump
- to the next handler CLEANUP or CATCH handler. */
- int depth; /* The THINK C profiler maintains a stack of called
- routines. Depth is used to pop the routines off of the
- profiler's stack. */
- } ExceptionTryType;
-
- extern ExceptionType gException; /* information about current exception */
- extern short _profile_depth; /* profiler stack depth */
-
- /* Raise an exception. Jumps to the next CLEANUP or CATCH handler. */
- #define RAISE \
- longjmp(gException.jmpenv, EXCEPTION_FAIL)
-
- /* Reset the error code and jump to the top of the TRY handler. */
- #define RETRY \
- { gException.err = _exception.err; longjmp(_exception.env, EXCEPTION_RETRY); }
-
- /* Reset the error code and clear failed flag. Used to prevent propagation of
- exceptions for routines such as call-backs which must return an error
- code. */
- #define NOPROPAGATE \
- { gException.err = _exception.err; _exception.failed = false; }
-
- /* The main body of the routine should be preceded by a TRY statement.
- This sets up the exception environment so that if an exception occurs
- execution will jump to the CLEANUP or CATCH handler. You must not
- return from the routine prior to the ENDTRY handler (or otherwise skip
- the ENDTRY handler, such as by use of a goto, break, continue, or
- longjmp). */
- #define TRY { volatile ExceptionTryType _exception; \
- _exception.depth = _profile_depth; \
- _exception.err = gException.err; \
- _exception.svenv = gException.jmpenv; \
- _exception.failed = (setjmp(_exception.env) == EXCEPTION_FAIL); \
- _profile_depth = _exception.depth; \
- if (! _exception.failed) { \
- gException.jmpenv = _exception.env; \
- {
-
- /* Statements which need to be executed whether or not the routine succeeds
- or fails should be placed after a CLEANUP statement. */
- #define CLEANUP } } \
- gException.jmpenv = _exception.svenv; \
- { {
-
- /* Statements which need to be executed only when an exception is raised
- should be placed after a CATCH statement. */
- #define CATCH } } \
- gException.jmpenv = _exception.svenv; \
- if (_exception.failed) { {
-
- /* Close the TRY handler and raise an exception if the failed flag is set. */
- #define ENDTRY } } \
- if (_exception.failed) \
- RAISE; \
- }
-
- OSErr FailReason(void);
- void FailActionSet(short action);
- void FailObjectSet(const CStr255 object);
- void FailExplanationSet(const CStr255 explanation);
- void FailInfoSet(short action, const CStr255 object, const CStr255 explanation);
- void FailInfoClear(void);
- void FailDisplay(void);
- void FailClear(void);
- void FailOSErr(OSErr err);
- void FailResError(void);
- void FailMemError(void);
- void FailPrError(void);
- void FailNILRes(void *);
- void FailNIL(void *);
-